package com.suray.wcs.service.hk.agv.system;

import com.suray.basic.wcs.utils.LoggerUtil;
import com.suray.wcs.service.hk.agv.HkAgv;
import com.suray.wcs.service.hk.agv.bean.HkAgvCallBack;
import com.suray.wcs.service.hk.agv.core.HkAgvTask;
import com.suray.wcs.service.hk.agv.exception.HkAgvProcessException;
import com.suray.wcs.service.hk.agv.system.process.HkAgvProcess;
import com.suray.wcs.service.hk.agv.type.HkAgvProcessType;
import com.suray.wcs.service.util.WcsUtil;

import java.util.ArrayList;
import java.util.List;

/**
 * 海康AGV总控制
 */
public class HkAgvImpl implements HkAgv {

    /**
     * 所有未完成的AGV流程
     */
    private List<HkAgvProcess> agvPros;

//    public HkAgvImpl() {
//        agvPros = new ArrayList<>();
//        init(new ArrayList<>());
//    }

    public HkAgvImpl(List<HkAgvTask> tasks) {
        agvPros = new ArrayList<>();
        init(tasks);
    }

    @Override
    public HkAgvTask generalTask(String startPreNode, String startNode, String endPreNode, String endNode, int taskType) {
        return createTask(startPreNode, startNode, endPreNode, endNode, taskType);
    }

    /**
     * 创建Agv任务
     * @param startPreNode
     * @param startNode
     * @param endPreNode
     * @param endNode
     * @return
     */
    private HkAgvTask createTask(String startPreNode, String startNode, String endPreNode, String endNode, int taskType) {
        HkAgvTask task = new HkAgvTask(startPreNode, startNode, endPreNode, endNode, taskType);
        LoggerUtil.info("Agv任务创建成功：" + task, this.getClass());
        startTask(task);
        return task;
    }

    /**
     * Agv到达点位后的任务信息返回
     * @param callBack
     * @return
     */
    @Override
    public boolean agvCallBack(HkAgvCallBack callBack) {
        HkAgvProcess process = findAgvProcess(Integer.valueOf(callBack.getTaskCode()));

        if (process == null) {
            throw new RuntimeException("未找到对应的Agv任务：" + callBack);
        }

        process.agvCallBack(callBack);

        return true;
    }

    @Override
    public void initTask(int taskId) {
        HkAgvProcess task = findAgvProcess(taskId);
        task.initTask();
    }

    @Override
    public void recoveryTask(int taskId) {
        HkAgvProcess task = findAgvProcess(taskId);
        task.recoveryTask();
    }

    @Override
    public void changeTaskProcess(int taskId, HkAgvProcessType process) {
        HkAgvProcess task = findAgvProcess(taskId);
        task.changeTaskProcess(process);
    }

    /**
     * 匹配日内瓦
     * @param taskId
     * @return
     */
    private HkAgvProcess findAgvProcess(int taskId) {
        for (HkAgvProcess process : agvPros) {
            if (process.getTask().getTaskId().equals(taskId)) {
                return process;
            }
        }

        return null;
    }

    /**
     * 初始化
     */
    public void init(List<HkAgvTask> tasks) {
        agvPros.clear();

        tasks.forEach(task -> {
            startTask(task);
        });
    }

    /**
     * 运行
     */
    public void run() {
        List<HkAgvProcess> endAgvPros = new ArrayList<>();

        agvPros.forEach(agvPro -> {
            if (agvPro.isProcessEnd()) {
                endAgvPros.add(agvPro);
            }
        });

        if (endAgvPros.size() > 0) {
            agvPros.removeAll(endAgvPros);
        }
    }

    /**
     * 启动任务
     */
    private void startTask(HkAgvTask task) {
        if (task.getIsExec()) {
            LoggerUtil.warn("该AGV任务已经在执行中：" + task, this.getClass());
            return;
        }

        try {
            HkAgvProcess agvPro = new HkAgvProcess(task);
            agvPro.init();

            agvPros.add(agvPro);
            LoggerUtil.info("Agv任务开始执行：" + task, this.getClass());
        } catch (HkAgvProcessException e) {
            WcsUtil.exceptionLog(e, this.getClass());
        }
    }
}
